namespace Angelus.Oracle.Entity.Common.Entity
{
    using System;
    using System.Collections.Generic;

    /// <summary>
    /// The symbol table is quite primitive - it is a stack with a new entry for
    /// each scope. Lookups search from the top of the stack to the bottom, until
    /// an entry is found.
    /// </summary>
    internal sealed class SymbolTable
    {
        #region Fields

        private readonly List<Dictionary<string, Symbol>> _symbols;

        #endregion

        #region Constructors

        /// <summary>
        /// 
        /// </summary>
        public SymbolTable()
        {
            this._symbols = new List<Dictionary<string, Symbol>>();
        }

        #endregion

        #region Table Management

        /// <summary>
        /// 
        /// </summary>
        internal void EnterScope()
        {
            this._symbols.Add(new Dictionary<string, Symbol>(StringComparer.OrdinalIgnoreCase));
        }

        /// <summary>
        /// 
        /// </summary>
        internal void ExitScope()
        {
            this._symbols.RemoveAt(this._symbols.Count - 1);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="symbol"></param>
        internal void Add(string name, Symbol symbol)
        {
            this._symbols[this._symbols.Count - 1][name] = symbol;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        internal Symbol Lookup(string name)
        {
            for (int index = this._symbols.Count - 1; index >= 0; --index)
            {
                if (this._symbols[index].ContainsKey(name))
                {
                    return this._symbols[index][name];
                }
            }

            return null;
        }

        #endregion
    }
}